package org.wang.portal.task;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.wang.portal.config.ConfigFileManager;
import org.wang.portal.param.PreMigrationValidator;
import org.wang.portal.status.TaskStatus;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TaskOrchestrator {
    private List<MigrationTask> tasks = new ArrayList<>();
    private Map<String, List<String>> taskTemplates = new HashMap<>();
    private Map<String, List<String>> customTemplates = new HashMap<>();

    public TaskOrchestrator() {
        loadTaskTemplates();
        loadCustomTemplates();
    }

    private void loadTaskTemplates() {
        JSONParser parser = new JSONParser();
        try (FileReader reader = new FileReader("config/task_templates.json")) {
            JSONObject jsonObject = (JSONObject) parser.parse(reader);
            taskTemplates.put("online_mode", (JSONArray) jsonObject.get("online_mode"));
            taskTemplates.put("offline_mode", (JSONArray) jsonObject.get("offline_mode"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void loadCustomTemplates() {
        JSONParser parser = new JSONParser();
        try (FileReader reader = new FileReader("config/custom_templates.json")) {
            JSONObject jsonObject = (JSONObject) parser.parse(reader);
            for (Object key : jsonObject.keySet()) {
                String templateName = (String) key;
                customTemplates.put(templateName, (JSONArray) jsonObject.get(templateName));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<String> getTemplateList() {
        List<String> templateList = new ArrayList<>();
        templateList.addAll(taskTemplates.keySet());
        templateList.addAll(customTemplates.keySet());
        System.out.println(templateList);
        return templateList;
    }

    private void saveCustomTemplates() {
        try (FileWriter file = new FileWriter("config/custom_templates.json")) {
            JSONObject jsonObject = new JSONObject();
            for (Map.Entry<String, List<String>> entry : customTemplates.entrySet()) {
                JSONArray jsonArray = new JSONArray();
                for (String item : entry.getValue()) {
                    jsonArray.add(item);
                }
                jsonObject.put(entry.getKey(), jsonArray);
            }
            file.write(jsonObject.toJSONString());
            file.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addTask(MigrationTask task) {
        tasks.add(task);
    }
    private boolean preCheck(Map<String, String> config) {
        PreMigrationValidator validator = new PreMigrationValidator();
        validator.validate(config);
        // 模拟前置检查逻辑
        System.out.println("Running pre-check for task: " + config.get("taskName"));
        return true; // 假设前置检查通过
    }
    public void executeTasksSequentially() throws IOException {
        preCheck(ConfigFileManager.getConfig());

        for (MigrationTask task : tasks) {
            MigrationTaskExecutor executor = new MigrationTaskExecutor(task);
            executor.execute();
            System.out.println("Task " + task.getName() + " status: " + task.getStatus());
            if (task.getStatus() == TaskStatus.FAILED) {
                System.out.println("Task " + task.getName() + " failed. Stopping the sequence.");
                break;
            }
        }
    }



    public void executeTemplate(String templateName) throws IOException {
        List<String> taskTypes = taskTemplates.get(templateName);
        if (taskTypes == null) {
            taskTypes = customTemplates.get(templateName);
        }
        if (taskTypes == null) {
            System.out.println("Template not found: " + templateName);
            return;
        }
        for (String taskType : taskTypes) {
            MigrationTask task = createTask(taskType, "Task_" + taskType, new HashMap<>());
            if (task != null) {
                addTask(task);
            }
        }

        executeTasksSequentially();
    }

    public void addCustomTemplate(String templateName, List<String> taskTypes) {
        if (taskTemplates.containsKey(templateName)) {
            System.out.println("Template name is reserved: " + templateName);
            return;
        }
        customTemplates.put(templateName, taskTypes);
        saveCustomTemplates();
        System.out.println("Custom template added: " + templateName);
    }

    public void updateCustomTemplate(String templateName, List<String> taskTypes) {
        if (taskTemplates.containsKey(templateName)) {
            System.out.println("Template name is reserved: " + templateName);
            return;
        }
        if (!customTemplates.containsKey(templateName)) {
            System.out.println("Custom template not found: " + templateName);
            return;
        }
        customTemplates.put(templateName, taskTypes);
        saveCustomTemplates();
        System.out.println("Custom template updated: " + templateName);
    }

    public void deleteCustomTemplate(String templateName) {
        if (taskTemplates.containsKey(templateName)) {
            System.out.println("Template name is reserved: " + templateName);
            return;
        }
        if (!customTemplates.containsKey(templateName)) {
            System.out.println("Custom template not found: " + templateName);
            return;
        }
        customTemplates.remove(templateName);
        saveCustomTemplates();
        System.out.println("Custom template deleted: " + templateName);
    }

    private MigrationTask createTask(String taskType, String name, Map<String, String> config) {
        switch (taskType) {
            case "ChameleonFullMigration":
                return new ChameleonFullMigrationTask(name, config, DatabaseType.MYSQL, DatabaseType.OPENGUASS);
            case "GsDataCheck":
                return new GsDataCheckTask(name, config);
            case "DebeziumIncrementalMigration":
                return new DebeziumIncrementalMigrationTask(name, config);
            case "ReverseMigration":
                return new ReverseMigrationTask(name, config);
            default:
                System.out.println("Unsupported task type: " + taskType);
                return null;
        }
    }

    public Map<String, Map<String, Object>> collectTaskStatusData() {
        Map<String, Map<String, Object>> statusData = new HashMap<>();
        for (MigrationTask task : tasks) {
            Map<String, Object> taskData = new HashMap<>();
            taskData.put("status", task.getStatus());
            taskData.put("startTime", task.getStartTime());
            taskData.put("endTime", task.getEndTime());
            taskData.put("progress", task.getProgress());
            statusData.put(task.getName(), taskData);
        }
        return statusData;
    }

}